package models

import (
	"encoding/json"
	"golang-blog/infrastructure/databases"
	"time"

	"gorm.io/gorm"
)

// User 用户
type User struct {
	// gorm.Model
	ID        int64     `json:"id" gorm:"primaryKey"`
	UserName  string    `gorm:"commont('用户名');uniqueIndex" json:"user_name"`
	NickName  string    `gorm:"comment('昵称')" json:"nickname"`           //昵称
	Account   string    `gorm:"comment('账号')" json:"account"`            //账号
	OpenidQq  string    `gorm:"comment('qq_openid')" json:"openid_qq"`   //qq
	Passwd    string    `gorm:"comment('密码')" json:"passwd"`             //密码
	Email     string    `gorm:"comment('邮箱')" json:"email"`              //邮箱
	Phone     string    `gorm:"comment('电话')" json:"phone"`              //电话号码
	Ecount    int       `gorm:"default 0;comment('错误次数')" json:"ecount"` //错误次数
	Ltime     time.Time `gorm:"comment('上次登录时间')" json:"ltime"`          //上次登录时间
	Ctime     time.Time `gorm:"comment('创建时间')" json:"ctime"`            //创建时间
	Status    int       `json:"status"`                                  // 小于0异常
	CreatedAt string    `json:"create_at"`
	UpdatedAt string    `json:"updated_at"`
	DeletedAt string    `json:"deleted_at"`
}

func (ci *User) String() string {
	a, _ := json.MarshalIndent(ci, "", "  ")
	return string(a)
}
func (a *User) BeforeCreate(tx *gorm.DB) (err error) {
	a.CreatedAt = time.Now().Format("2006-01-02 15:04:05")
	a.UpdatedAt = a.CreatedAt
	return
}

func (a *User) BeforeUpdate(tx *gorm.DB) (err error) {
	a.UpdatedAt = time.Now().Format("2006-01-02 15:04:05")
	return
}
func (a *User) BeforeDelete(tx *gorm.DB) (err error) {
	a.DeletedAt = time.Now().Format("2006-01-02 15:04:05")
	return
}

// 文章的增删改查操作

type Users struct {
	wheres User
	Arts   []User
	txn    *gorm.DB
}

func NewUser(tx *gorm.DB) *Users {
	if tx == nil {
		tx = databases.GetDB()
	}
	return &Users{
		txn:  tx,
		Arts: make([]User, 1, 32),
	}
}

func (a *Users) With(art *User) *Users {
	a.Arts[0] = *art
	return a
}
func (as *Users) Where(a *User) *Users {
	as.wheres = *a
	return as
}
func (as *Users) FirstOrCreate() error {
	txn := as.txn.Debug().Where(&as.wheres).Attrs(&as.Arts)
	if err := txn.FirstOrCreate(&as.Arts[0]).Error; err != nil {
		return err
	}
	return nil
}
func (as *Users) Create() error {
	txn := as.txn.Debug().Model(&User{})
	if err := txn.Create(&as.Arts).Error; err != nil {
		return err
	}
	return nil
}
func (as *Users) First() (*User, error) {
	txn := as.txn.Debug().Model(&User{}).Where(&as.wheres)
	if err := txn.First(&as.Arts).Error; err != nil {
		return nil, err
	}
	return &as.Arts[0], nil
}
func (a *Users) QueryRange(page, pageSize int) (*[]User, int, int, error) {
	var (
		count     int64
		totalPage int
	)
	txn := a.txn.Debug().Model(&User{}).Where(&a.wheres)
	if err := txn.Order("id").Offset((page - 1) * pageSize).Limit(pageSize).Find(&a.Arts).Error; err != nil {
		return nil, 0, 0, err
	}
	if err := txn.Count(&count).Error; err != nil {
		return nil, 0, 0, err
	}
	if int(count)%pageSize != 0 {
		totalPage = int(count)/pageSize + 1
	} else {
		totalPage = int(count) / pageSize
	}
	return &a.Arts, len((*a).Arts), totalPage, nil
}
func (a *Users) Update() error {
	txn := a.txn.Debug().Model(&User{}).Where(&a.wheres)
	if err := txn.Updates(&a.Arts[0]).Error; err != nil {
		return err
	}
	return nil
}
func (a *Users) Delete() error {
	txn := a.txn.Debug().Model(&User{}).Where(&a.wheres)
	if err := txn.Delete(&a.Arts).Error; err != nil {
		return err
	}
	return nil
}
func (a *Users) Counts() (int64, error) {
	var count int64
	txn := a.txn.Debug().Model(&User{}).Where(&a.wheres)
	if err := txn.Count(&count).Error; err != nil {
		return 0, err
	}
	return count, nil
}

func (a *Users) Last() (*User, error) {
	txn := a.txn.Debug().Model(&User{}).Where(&a.wheres)
	if err := txn.Last(&a.Arts).Error; err != nil {
		return nil, err
	}
	return &a.Arts[0], nil
}
